//
// Created by Administrator on 2024/7/10.
//

#ifndef BASE_H
#define BASE_H

#include <array>
#include <string>
#include <vector>

#include "concepts.hpp"
#include "utils.hpp"
#include "macros.hpp"

namespace common {

class MessagePackReader;
class MessagePackWriter;

class Sizeable {
protected:
    [[nodiscard]] virtual size_t size() const = 0;

public:
    virtual ~Sizeable() = default;

    friend size_t size(const Sizeable &object);
};

inline size_t size(const Sizeable &object) {
    return object.size();
}

// 基础版本的size_of函数，用于处理基本类型
template<typename T>
constexpr size_t size_of(const T&) {
    return sizeof(T);
}

// 特化版本的size_of函数，用于处理std::vector
template<typename T, typename Allocator>
constexpr size_t size_of(const std::vector<T, Allocator>& vec) {
    return vec.size() * size(vec.at(0));
}

// 特化版本的size_of函数，用于处理std::array
template<typename T, std::size_t N>
constexpr size_t size_of(const std::array<T, N>& arr) {
    return N * sizeof(T);
}

// 特化版本的 size_of 函数，用于处理所有继承自 Sizeable 的类型
template<DerivedFrom<Sizeable> T>
constexpr size_t size_of(const T& sizeable) {
    return size(sizeable);
}

template<DerivedSmartPointerFrom<Sizeable> T>
constexpr size_t size_of(const T& sizeable) {
    return size(*sizeable);
}

// 特化版本的 size_of 函数，用于处理所有继承自 Sizeable 的类型
template<DerivedPointerFrom<Sizeable> T>
constexpr size_t size_of(const T& sizeable) {
    return size(*sizeable);
}

/**
 * 自动实现size方法
 */
#define IMPLEMENT_SIZEABLE(...) \
protected: \
[[nodiscard]] size_t size() const override { \
    return BRACKETS(EXPAND(APPLY(common::size_of, + , __VA_ARGS__))); \
}

class Serializable {
public:
    virtual ~Serializable() = default;

    virtual void serialize(MessagePackWriter &writer) = 0;

    virtual void deserialize(MessagePackReader &reader) = 0;
};

class ToString {
public:
    virtual ~ToString() = default;

    [[nodiscard]] virtual std::string toString() const = 0;
};

template<typename T>
std::string to_string(T &var) {
    return common::toHex(&var, common::size_of(var));
}

template<DerivedFrom<ToString> T>
std::string to_string(T &var) {
    auto str = var.toString();
    str = str.substr(0, str.size() - 1);
    return str;
}

template<DerivedSmartPointerFrom<ToString> T>
std::string to_string(T &var) {
    auto str = var->toString();
    str = str.substr(0, str.size() - 1);
    return str;
}

template<DerivedPointerFrom<ToString> T>
std::string to_string(T &var) {
    auto str = var->toString();
    str = str.substr(0, str.size() - 1);
    return str;
}

#define TOSTRING(x) (#x + std::string(" = {") + common::to_string(x) + "}\n")
    /**
 * 自动实现toString方法
 */
#define IMPLEMENT_TOSTRING(...) \
public: \
[[nodiscard]] std::string toString() const override { \
std::stringstream ss; \
if (1 == common::count_args(__VA_ARGS__)) ss << common::to_string(common::get_first_arg(__VA_ARGS__)); \
else ss << EXPAND(APPLY(TOSTRING, << , __VA_ARGS__)); \
return common::replace_all(common::replace_all(ss.str(), "_ =", " ="), "*", ""); \
}

}

#endif //BASE_H
